package com.mls.fivedistrict.server.impl;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;

import com.github.pagehelper.util.StringUtil;
import com.mls.fivedistrict.common.PageFilter;
import com.mls.fivedistrict.common.ServiceResponse;
import com.mls.fivedistrict.dao.PropertyMapper;
import com.mls.fivedistrict.dao.RecordMapper;
import com.mls.fivedistrict.dao.ReportMapper;
import com.mls.fivedistrict.enums.RecordStatusEnum;
import com.mls.fivedistrict.enums.ResponseCode;
import com.mls.fivedistrict.exception.CustomerException;
import com.mls.fivedistrict.pojo.*;
import com.mls.fivedistrict.server.*;
import com.mls.fivedistrict.util.jedis.RedisPoolUtil;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.*;

import static java.math.BigDecimal.ROUND_DOWN;

/**
 * Created by nanji on 2018/3/16.
 */
@Service("recordService")
public class RecordServiceImpl implements RecordService {

    @Resource(name = "recordMapper")
    private RecordMapper recordMapper;
    @Resource(name = "propertyMapper")
    private PropertyMapper propertyMapper;
    @Resource(name = "reportMapper")
    private ReportMapper reportMapper;
    @Resource(name = "propertyService")
    private PropertyService propertyService;
    @Resource(name = "orePoolService")
    private OrePoolService orePoolService;
    @Resource(name = "userService")
    private UserService userService;
    @Resource(name = "loseRecordService")
    private LoseRecordService loseRecordService;


    @Transactional
    @Override
    public ServiceResponse addRecord(Record record) {
        int row = recordMapper.insertSelective(record);
        if (row > 0) {
            return ServiceResponse.createSuccessResponse("插入成功");
        }
        return ServiceResponse.createErrorResponse("插入失败");
    }

    @Transactional
    @Override
    public ServiceResponse deleteRecord(Long recordId) {
        int row = recordMapper.deleteByPrimaryKey(recordId);
        if (row > 0) {
            return ServiceResponse.createSuccessResponse("删除成功");
        }
        return ServiceResponse.createErrorResponse("删除失败");
    }

    @Override
    public ServiceResponse getRecordList(PageFilter pageFilter) {
        Map<String, String> maps = pageFilter.getFilterMap();
        Map<String, Object> params = new HashMap<>();
        maps.forEach((k, v) -> {
            if (!StringUtil.isEmpty(v)) {
                params.put(k, v);
            }
        });
        List<Record> userIntegralReportList = new ArrayList<>();
        int recordCount = reportMapper.getUserIntegralReportsCount(params);
        int receiveRecordCount = reportMapper.getUserIntegralReceiverReportsCount(params);
        int count = recordCount + receiveRecordCount;
        int startIndex = (pageFilter.getPageNum() - 1) * pageFilter.getPageSize();
        int endIndex = startIndex + pageFilter.getPageSize();
        if (recordCount >= endIndex) {
            params.put("startIndex", startIndex);
            params.put("dataSize", pageFilter.getPageSize());
            userIntegralReportList = reportMapper.getUserIntegralReports(params);
        } else if (recordCount > startIndex && endIndex > recordCount) {
            params.put("startIndex", startIndex);
            params.put("dataSize", pageFilter.getPageSize());
            userIntegralReportList = reportMapper.getUserIntegralReports(params);
            params.put("startIndex", 0);
            params.put("dataSize", pageFilter.getPageSize() - userIntegralReportList.size());
            List<Record> userIntegralReceiveReportList = reportMapper.getUserIntegralReceiverReports(params);
            userIntegralReportList.addAll(userIntegralReceiveReportList);
        } else if (recordCount <= startIndex && count > startIndex) {
            params.put("startIndex", startIndex - recordCount);
            params.put("dataSize", pageFilter.getPageSize());
            userIntegralReportList = reportMapper.getUserIntegralReceiverReports(params);
        }
        Page pages = new Page();
        for (Record r : userIntegralReportList) {
            pages.add(r);
        }
        pages.setTotal(count);
        pages.setPageNum(pageFilter.getPageNum());
        double p = Math.ceil(count * 1.0 / pageFilter.getPageSize());
        pages.setPages((int) p);
        PageInfo pageInfo = new PageInfo(pages, 8);
        return ServiceResponse.createSuccessResponse(pageInfo);
    }


    @Override
    public ServiceResponse getRecordListByApp(PageFilter pageFilter) {
        RecordExample recordExample = new RecordExample();
        RecordExample.Criteria criteria = recordExample.createCriteria();
        String status = pageFilter.getFilterMap().get("status");
        if (!StringUtil.isEmpty(status)) {
            criteria.andStatusEqualTo(status);
        }
        String intergralId = pageFilter.getFilterMap().get("intergralId");
        if (!StringUtil.isEmpty(intergralId)) {
            criteria.andIntergralIdEqualTo(Long.valueOf(intergralId));
        }
        String propertyId = pageFilter.getFilterMap().get("propertyId");
        if (!StringUtil.isEmpty(propertyId)) {
            criteria.andPropertyIdEqualTo(Long.valueOf(propertyId));
        }
        String userId = pageFilter.getFilterMap().get("userId");
        if (!StringUtil.isEmpty(userId)) {
            criteria.andUserIdEqualTo(Long.valueOf(userId));
        }
        if (!StringUtil.isEmpty(pageFilter.getOrderCause())) {
            recordExample.setOrderByClause(pageFilter.getOrderCause());
        }
        criteria.andIsDeleteEqualTo(false);
        PageHelper.startPage(pageFilter.getPageNum(), pageFilter.getPageSize());
        List<Record> records = recordMapper.selectByExample(recordExample);
        PageInfo pageInfo = new PageInfo(records, 5);
        return ServiceResponse.createSuccessResponse(pageInfo);
    }

    @Override
    public List<Record> getRecordListSingle(PageFilter pageFilter) {
        RecordExample recordExample = new RecordExample();
        RecordExample.Criteria criteria = recordExample.createCriteria();
        Optional.ofNullable(pageFilter.getFilterMap().get("status")).map(status -> criteria.andStatusEqualTo(status));
        Optional.ofNullable(pageFilter.getFilterMap().get("intergralId")).map(intergralId -> criteria.andIntergralIdEqualTo(Long.valueOf(intergralId)));
        Optional.ofNullable(pageFilter.getFilterMap().get("propertyId")).map(propertyId -> criteria.andPropertyIdEqualTo(Long.valueOf(propertyId)));
        Optional.ofNullable(pageFilter.getFilterMap().get("userId")).map(userId -> criteria.andUserIdEqualTo(Long.valueOf(userId)));
        if (!StringUtil.isEmpty(pageFilter.getOrderCause())) {
            recordExample.setOrderByClause(pageFilter.getOrderCause());
        }
        criteria.andIsDeleteEqualTo(false);
        PageHelper.startPage(pageFilter.getPageNum(), pageFilter.getPageSize());
        List<Record> records = recordMapper.selectByExampleSingle(recordExample);
        return records;
    }

    @Override
    public List<Record> getRecordListByTask() {
        RecordExample recordExample = new RecordExample();
        RecordExample.Criteria criteria = recordExample.createCriteria();
        criteria.andStatusEqualTo(RecordStatusEnum.WAITRECEIVE.getValue());
        long lastTime = new Date().getTime() - 72 * 60 * 60 * 1000;
        criteria.andCreateDateLessThan(new Date(lastTime));
        //有可能用户实名认证被驳回还有未领取的记录
//        criteria.andIsDeleteEqualTo(false);
        List<Record> records = recordMapper.selectByExample(recordExample);
        return records;
    }


    @Override
    public ServiceResponse editRecord(Record record) {
        int i = recordMapper.updateByPrimaryKeySelective(record);
        if (i > 0) {
            return ServiceResponse.createSuccessResponse();
        } else {
            return ServiceResponse.createErrorResponse("操作失败");
        }
    }

    @Override
    public Record getRecordDetail(Long recordId) {
        Record record = recordMapper.selectByPrimaryKey(recordId);
        return record;
    }

    @Override
    public int insertBash(List<Record> list) {
        int i = recordMapper.insertBatch(list);
        return i;
    }

    @Transactional
    @Override
    public int acceptRecord(Long recordId, Long userId) {
        Record record = getRecordDetail(recordId);
        Optional.ofNullable(record).orElseThrow(() -> new CustomerException("记录不存在"));
        if (!record.getUserId().equals(userId)) {
            throw new CustomerException("无权限操作");
        }
        if (!record.getStatus().equals(RecordStatusEnum.WAITRECEIVE.getValue())) {


            throw new CustomerException("点击太快了");
        }
        record.setStatus(RecordStatusEnum.ALREADYRECEIVE.getValue());
        //减少矿池剩余数量
        Long orePoolId = record.getOrePoolId();
        BigDecimal value = record.getValue();
        OrePool orePoolDetail = orePoolService.getOrePoolDetail(orePoolId);
        BigDecimal residue = orePoolDetail.getResidue();
        BigDecimal bigDecimal = residue.subtract(value).setScale(8, ROUND_DOWN);//剩余积分
        OrePool orePool = new OrePool();
        orePool.setId(orePoolId);
        orePool.setResidue(bigDecimal);
        orePoolService.editOrePool(orePool);
        String propertyRedisKey = record.getUserId() + "_" + record.getIntergralId();
        int row = updateRecordForReceive(record);
        if (row > 0) {
            //更新用户资产
            String propertyIdStr = RedisPoolUtil.get(propertyRedisKey);
            if (StringUtil.isEmpty(propertyIdStr)) {
                ServiceResponse propertyResponse = propertyService.getPropertyByIntegral(record.getIntergralId(), record.getUserId());
                if (propertyResponse.getState().equals(ResponseCode.SUCCESS.getCode())) {
                    Property property = (Property) propertyResponse.getData();
                    RedisPoolUtil.setEx(propertyRedisKey, property.getId() + "", 60 * 5);
                    propertyService.editPropertyByRecord(property.getId(), record.getValue());

                } else {
                    //代表资产不存在 第一次创建
                    Property property = new Property();
                    property.setIntegralId(record.getIntergralId());
                    property.setUserId(record.getUserId());
                    property.setTotal(record.getValue());
                    propertyService.addProperty(property);
                }
            } else {
                //代表Redis中有缓存
                propertyService.editPropertyByRecord(Long.valueOf(propertyIdStr), record.getValue());
            }

        }
        return row;
    }

    @Override
    public BigDecimal getRecordSum() {
        String sum = RedisPoolUtil.get("recordSum");
        BigDecimal recordSum;
        if (StringUtil.isEmpty(sum)) {
            recordSum = recordMapper.getRecordSum();
            RedisPoolUtil.setEx("m", recordSum + "", 1 * 60 * 60);
        } else {
            recordSum = new BigDecimal(sum);
        }

        return recordSum;
    }

    @Override
    public int insertSelect(Record record) {
        int row = recordMapper.insertSelective(record);
        return row;
    }

    @Override
    public int insertRecord(Record record) {
        int i = recordMapper.insertSelective(record);
        return i;
    }

    @Override
    public List<Record> getRecordListByPropertyId(Long propertyId) {
        RecordExample recordExample = new RecordExample();
        RecordExample.Criteria criteria = recordExample.createCriteria();
        criteria.andPropertyIdEqualTo(propertyId);
        criteria.andIsDeleteEqualTo(false);
        List<Record> records = recordMapper.selectByExample(recordExample);
        return records;
    }

    @Override
    public List<Record> getRecordListByUserId(Long userId) {
        RecordExample recordExample = new RecordExample();
        RecordExample.Criteria criteria = recordExample.createCriteria();
        criteria.andUserIdEqualTo(userId);
        criteria.andIsDeleteEqualTo(false);
        List<Record> records = recordMapper.selectByExample(recordExample);
        return records;
    }

    @Override
    public void deleteBatch(List<Record> recordList) {
        recordMapper.deleteBatch(recordList);

    }

    @Override
    public List<Record> getRecordList(Long integralId, Long userId) {
//        RecordExample recordExample = new RecordExample();
//        RecordExample.Criteria criteria = recordExample.createCriteria();
//        criteria.andUserIdEqualTo(userId);
//        criteria.andIsDeleteEqualTo(false);
//        criteria.andIntergralIdEqualTo(integralId);
        Map map = new HashMap();
        map.put("integralId", integralId);
        map.put("userId", userId);
        List<Record> records = recordMapper.selectAllRecord(map);
        return records;
    }

    @Override
    public List<RecordAndIntegral> searchAndIntegral(Map<String, String> params) {
        List<RecordAndIntegral> recordAndIntegralList = recordMapper.searchAndIntegral(params);
        return recordAndIntegralList;
    }

    @Transactional
    @Override
    public int deleteTransferRecord(Date createDate) {
        return recordMapper.deleteTranceRecord(createDate);
    }

    @Transactional
    @Override
    public void recycleBatch(List<Record> recordList) {
        if (recordList.size() > 0) {
            //每10000条执行一次进行插入
            //总共执行多少次
            int totlaSplice = 10000;
            int times = (int) Math.ceil(recordList.size() * 1.0 / totlaSplice);
            if (times > 1) {
                for (int i = 0; i < times; i++) {
                    List<Record> timeRecords = new ArrayList<>();
                    int sum = recordList.size();
                    if ((i + 1) * totlaSplice < recordList.size()) {
                        sum = (i + 1) * totlaSplice;
                    }
                    for (int t = i * totlaSplice; t < sum; t++) {
                        timeRecords.add(recordList.get(t));
                    }
                    int i1 = loseRecordService.insertBash(timeRecords);
                    if (i1 > 0) {
                        int row = recordMapper.deleteBatchReal(timeRecords);
                        if (row <= 0) {
                            throw new CustomerException("执行出错");
                        }
                    }
                }
            } else {
                int i1 = loseRecordService.insertBash(recordList);
                if (i1 > 0) {
                    int row = recordMapper.deleteBatchReal(recordList);
                    if (row <= 0) {
                        throw new CustomerException("执行出错");
                    }
                }
            }


        }

    }

    @Override
    public int updateRecordForReceive(Record record) {
        return recordMapper.updateForReceive(record);
    }

    @Override
    public long getMaxId(Date createDate) {
        long maxId = recordMapper.getMaxId(createDate);
        return maxId;
    }

    @Override
    public Long insertRecordForId(Record record) {
        int i = recordMapper.insertSelective(record);
        if (i <= 0) {
            throw new CustomerException("添加记录出错");
        }
        return record.getId();
    }


}
